/*
 * GHumanUser.java
 * Created on 18 juin 2007
 *
 * Glacéo Internet Platform
 * http://sourceforge.net/projects/chm/
 *
 * Copyright (c) 2005-2009, Jens and Jan Janke (VirtualHockey Project)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.hockeo.vhbase.data.dao.user;


import java.util.GregorianCalendar;

import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;

import org.apache.commons.codec.binary.Hex;

import com.hockeo.vhbase.data.dao.IGEntity;
import com.hockeo.vhbase.data.dao.club.GClub;
import com.hockeo.vhbase.error.GException;
import com.hockeo.vhbase.utils.data.GPasswordService;

/**
 * Represents a human user that manages a particular club or is currently unemployed.
 *
 * @version $Id$
 * @author jjanke
 */
@Entity
@DiscriminatorValue( "HU" )
public class GHumanUser extends GUser
{
  @Column( name = "hu_password_hash" )
  private String            d_strPasswordHash;

  @Column( name = "hu_email" )
  private String            d_strEmail;

  @Column( name = "hu_country" )
  private String            d_strCountry;

  @Column( name = "hu_town" )
  private String            d_strTown;

  @Column( name = "hu_authorization_date" )
  private GregorianCalendar d_calAuthorizationDate;

  /** Default parameterless constructor. */
  protected GHumanUser()
  {
    super();
  }

  public String getEmail()
  {
    return d_strEmail;
  }

  public void setEmail( String email )
  {
    d_strEmail = email;
  }

  public String getCountry()
  {
    return d_strCountry;
  }

  public void setCountry( String country )
  {
    d_strCountry = country;
  }

  public String getTown()
  {
    return d_strTown;
  }

  public void setTown( String town )
  {
    d_strTown = town;
  }

  public GregorianCalendar getAuthorizationDate()
  {
    return d_calAuthorizationDate;
  }

  public void setAuthorizationDate( GregorianCalendar authorizationDate )
  {
    d_calAuthorizationDate = authorizationDate;
  }

  /**
   * Returns whether this account has been authorized or not. Non authorized accounts are
   * deleted after a certain amount of time.
   */
  public boolean isAuthorized()
  {
    return d_calAuthorizationDate != null;
  }

  /**
   * Returns the club that is currently managed by this user.
   *
   * @return the managed club or <code>null</code> if the user is currently 'unemployed'
   * @throws IllegalStateException if more than one club is attached to this user
   */
  public GClub getCurrentClub()
  {
    if ( getCurrentClubs().size() == 1 )
      return getCurrentClubs().get( 0 );
    else if ( getCurrentClubs().isEmpty() )
      return null;
    else
      throw new IllegalStateException( "A human user is not allowed to manage more than one club!" );
  }

  /**
   * Takes the given plain text user password, creates a hash over it and stores the hash.
   * The plain text password is not saved anywhere. Only the generated hash is kept.
   *
   * @param strPasswordAsPlainText the password that shall be set for the VHUser
   * @throws GException if an error occured while trying to compute a hash for the
   *           password
   */
  public void setPassword( String strPasswordAsPlainText ) throws GException
  {
    d_strPasswordHash = computeHash( strPasswordAsPlainText );
  }

  /**
   * Compares the password given as a parameter to the one originally defined by the user.
   * This method creates a hash over the passed plain text password and then compares the
   * generated hash with the hash of the originally stored password.
   *
   * @param strPasswordAsPlainText the password that shall be compared against the
   *          password defined in this user object
   * @return <code>true</code> if the hash codes of both passwords are identical,
   *         <code>false</code> otherwise
   * @throws GException if an error occured while trying to compute a hash for the
   *           password
   */
  public boolean comparePassword( String strPasswordAsPlainText ) throws GException
  {
    String compareHash = computeHash( strPasswordAsPlainText );

    return d_strPasswordHash.equals( compareHash );
  }

  /*
   * @see com.hockeo.vhbase.data.GUser#getTypeCode()
   */
  @Override
  public String getTypeCode()
  {
    return "HU";
  }

  public Class<? extends IGEntity> getGEntityClass()
  {
    return GHumanUser.class;
  }

  /**
   * Computes an MD5 hash and encodes it as hexadecimal value.
   *
   * @param strPlainText the string to be encoded
   * @return the MD5 hex encoded version of the passed plain text value
   * @throws VHException if an error occured while trying to compute a hash for the
   *           password
   */
  private String computeHash( String strPlainText ) throws GException
  {
    return new String( Hex.encodeHex( GPasswordService.getInstance().computeMD5( strPlainText ) ) );
  }
}
